package gen.desktop.components;

import gen.core.GenUtils;
import gen.core.Generator;
import gen.core.TemplateManager;
import gen.core.exceptions.GenException;
import gen.core.models.Template;
import gen.desktop.Helper;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.sql.Connection;

import javax.swing.DefaultComboBoxModel;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSeparator;
import javax.swing.JSplitPane;
import javax.swing.JTextArea;
import javax.swing.JToolBar;
import javax.swing.SwingConstants;

import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;

public class GenByArraysPanel extends JPanel {
	private static final String CATAGORY = "GenByArrays";
	private static final int MAX_ARRAYS_ROW_SIZE = 256;

	private static final long serialVersionUID = 1L;
	private JSplitPane splitPane_main;
	private JSplitPane splitPane_sub;
	private JTextArea textArea_arrays;
	private JTextArea textArea_template;
	private JTextArea textArea_result;
	private JSeparator separator;
	private JLabel lblNewLabel;
	private JComboBox comboBox;
	private JPanel panel;
	private JToolBar toolBar_1;
	private JButton btnSaveButton;
	private JButton btnSaveAsButton;
	private JButton btnDeleteButton;
	private JSeparator separator_1;

	/**
	 * Create the panel.
	 */
	public GenByArraysPanel() {
		setLayout(new BorderLayout(0, 0));

		JToolBar toolBar = new JToolBar();
		toolBar.setFloatable(false);
		add(toolBar, BorderLayout.NORTH);

		separator = new JSeparator();
		separator.setOrientation(SwingConstants.VERTICAL);
		toolBar.add(separator);

		JButton btnNewButton_gen = new JButton("生成");
		btnNewButton_gen.setIcon(new ImageIcon(GenByArraysPanel.class.getResource("/gen/desktop/icons/size16x16/cog.png")));
		btnNewButton_gen.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				GenByArraysPanel.this.generate();
			}
		});
		btnNewButton_gen.setFont(new Font("宋体", Font.PLAIN, 12));
		toolBar.add(btnNewButton_gen);

		splitPane_main = new JSplitPane();
		splitPane_main.setOrientation(JSplitPane.VERTICAL_SPLIT);
		add(splitPane_main, BorderLayout.CENTER);

		splitPane_sub = new JSplitPane();
		splitPane_main.setLeftComponent(splitPane_sub);

		JScrollPane scrollPane = new JScrollPane();
		splitPane_sub.setLeftComponent(scrollPane);

		textArea_arrays = new JTextArea();
		scrollPane.setViewportView(textArea_arrays);

		panel = new JPanel();
		splitPane_sub.setRightComponent(panel);
		panel.setLayout(new BorderLayout(0, 0));

		toolBar_1 = new JToolBar();
		toolBar_1.setFloatable(false);
		panel.add(toolBar_1, BorderLayout.NORTH);

		lblNewLabel = new JLabel("载入模版：");
		toolBar_1.add(lblNewLabel);
		lblNewLabel.setHorizontalAlignment(SwingConstants.LEFT);

		comboBox = new JComboBox();
		toolBar_1.add(comboBox);
		comboBox.setMaximumRowCount(10);
		comboBox.setFont(new Font("宋体", Font.PLAIN, 12));

		separator_1 = new JSeparator();
		separator_1.setOrientation(SwingConstants.VERTICAL);
		toolBar_1.add(separator_1);

		btnSaveButton = new JButton("保存");
		btnSaveButton.setFont(new Font("宋体", Font.PLAIN, 12));
		btnSaveButton.setIcon(new ImageIcon(GenByArraysPanel.class.getResource("/gen/desktop/icons/size16x16/disk.png")));
		btnSaveButton.setToolTipText("");
		toolBar_1.add(btnSaveButton);

		btnSaveAsButton = new JButton("另存为");
		btnSaveAsButton.setFont(new Font("宋体", Font.PLAIN, 12));
		btnSaveAsButton.setIcon(new ImageIcon(GenByArraysPanel.class.getResource("/gen/desktop/icons/size16x16/save_as.png")));
		toolBar_1.add(btnSaveAsButton);

		btnDeleteButton = new JButton("删除");
		btnDeleteButton.setIcon(new ImageIcon(GenByArraysPanel.class.getResource("/gen/desktop/icons/size16x16/delete.png")));
		toolBar_1.add(btnDeleteButton);

		JScrollPane scrollPane_1 = new JScrollPane();
		panel.add(scrollPane_1, BorderLayout.CENTER);

		textArea_template = new JTextArea();
		scrollPane_1.setViewportView(textArea_template);

		JScrollPane scrollPane_3 = new JScrollPane();
		splitPane_main.setRightComponent(scrollPane_3);

		textArea_result = new JTextArea();
		scrollPane_3.setViewportView(textArea_result);
	}

	public void centerDivider() {
		splitPane_main.setDividerLocation(0.5);
		splitPane_sub.setDividerLocation(0.5);
		Dimension aDimension = comboBox.getPreferredSize();
		aDimension.setSize(aDimension.getWidth(), aDimension.getHeight());
		comboBox.setMaximumSize(aDimension);
	}

	public void init() {
		// 居中所有分割线
		centerDivider();

		// 将模板列表装载到模板下拉框中
		loadTemplateListToComboBox();

		// 相应模板下拉框，切换模板输入框中的内容
		comboBox.addItemListener(new ItemListener() {
			public void itemStateChanged(ItemEvent e) {
				if (e.getStateChange() == java.awt.event.ItemEvent.SELECTED) {
					Template aTemplate = (Template) e.getItem();
					GenByArraysPanel.this.textArea_template.setText(aTemplate.getContent());
				}
			}
		});

		// 相应保存按钮，保存模板到数据库中
		btnSaveButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				Template selectedTemplate = (Template) comboBox.getSelectedItem();
				Connection conn = null;
				TemplateManager aTemplateManager = new TemplateManager();

				try {
					conn = Helper.getSqliteClient().createConnection();
					if (StringUtils.isBlank(selectedTemplate.getId())) {
						throw new GenException(null, "模版名不能为空！");
					}

					Template aTemplate = aTemplateManager.load(conn, selectedTemplate.getId());
					aTemplate.setContent(GenByArraysPanel.this.textArea_template.getText());
					aTemplateManager.save(conn, aTemplate);
					conn.commit();

					selectedTemplate.setContent(aTemplate.getContent());
				} catch (Exception ex) {
					JOptionPane.showMessageDialog(null, ex.getMessage(), "模版保存失败！", JOptionPane.ERROR_MESSAGE);
					return;
				} finally {
					GenUtils.closeConnection(conn);
				}
			}
		});

		// 相应另存为按钮，创建新的模版并存入数据库
		btnSaveAsButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				// 保存新模版
				Connection conn = null;
				TemplateManager aTemplateManager = new TemplateManager();
				Template aTemplate = new Template();

				try {
					// 提示输入新模版的名称
					String aName = JOptionPane.showInputDialog(null, "请输入新模版的名称:");
					if (aName == null) // 因为点击了取消取消，所以方法直接静默返回
						return; 
					if (StringUtils.isBlank(aName)) {
						throw new GenException(null, "无效的模版名称！");
					}

					conn = Helper.getSqliteClient().createConnection();

					aTemplate.setName(aName);
					aTemplate.setCatagory(CATAGORY);
					aTemplate.setContent(GenByArraysPanel.this.textArea_template.getText());
					aTemplate.setOwner(Helper.getOwner());
					aTemplateManager.save(conn, aTemplate);

					conn.commit();
				} catch (Exception ex) {
					JOptionPane.showMessageDialog(null, ex.getMessage(), "模版另存失败！", JOptionPane.ERROR_MESSAGE);
					return;
				} finally {
					GenUtils.closeConnection(conn);
				}

				// 刷新模版下拉框，并置下拉框当前项为新保存的模版
				loadTemplateListToComboBox();
				for (int i = 1; i < comboBox.getItemCount(); i++) {
					Template curTemplate = (Template) comboBox.getItemAt(i);
					if (curTemplate.getId().equals(aTemplate.getId())) {
						comboBox.setSelectedIndex(i);
					}
				}
			}
		});

		// 相应删除按钮，删除选中的模版
		btnDeleteButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				Connection conn = null;
				Template selectedTemplate = (Template) comboBox.getSelectedItem();
				TemplateManager aTemplateManager = new TemplateManager();

				try {
					conn = Helper.getSqliteClient().createConnection();
					if (StringUtils.isBlank(selectedTemplate.getId())) {
						return;
					}

					aTemplateManager.delete(conn, selectedTemplate.getId());
					conn.commit();
				} catch (Exception ex) {
					JOptionPane.showMessageDialog(null, ex.getMessage(), "模版删除失败！", JOptionPane.ERROR_MESSAGE);
					return;
				} finally {
					GenUtils.closeConnection(conn);
				}

				comboBox.removeItem(selectedTemplate);
			}
		});
	}

	private void loadTemplateListToComboBox() {
		TemplateManager aTemplateManager = new TemplateManager();
		Connection conn = null;
		try {
			conn = Helper.getSqliteClient().createConnection();
			Template[] templateArray = aTemplateManager.list(conn, Helper.getOwner(), CATAGORY);
			comboBox.setModel(new DefaultComboBoxModel(ArrayUtils.add(templateArray, 0, new Template())));
		} finally {
			GenUtils.closeConnection(conn);
		}
	}

	public void generate() {
		String arraysString = this.textArea_arrays.getText();
		String templateString = this.textArea_template.getText();

		String[] rows = arraysString.split("\\n");
		String[][] arrays = new String[rows.length][MAX_ARRAYS_ROW_SIZE];

		final String DEFAULT_STRING = "";
		for (int i = 0; i < rows.length; i++) {
			for (int j = 0; j < MAX_ARRAYS_ROW_SIZE; j++) {
				arrays[i][j] = DEFAULT_STRING;
			}

			String[] tokens = rows[i].trim().split("\\s+");
			for (int j = 0; j < tokens.length; j++) {
				arrays[i][j] = tokens[j];
			}
		}

		try {
			Generator aGenerator = new Generator();
			aGenerator.init();
			String result = aGenerator.genByArrays(arrays, templateString);
			this.textArea_result.setText(result);
		} catch (Exception ex) {
			JOptionPane.showMessageDialog(null, ex.getMessage(), "代码生成失败！", JOptionPane.ERROR_MESSAGE);
			return;
		}

	}
}
